/********************************************************************
	created:	20:4:2010   17:02
	filename: 	hy_tss.h
	author:		zxh
	purpose:	tls (thread local storage)
*********************************************************************/
#ifndef _HY_TSS_H_
#define _HY_TSS_H_

#if defined(_WIN32)

#else
#include <pthread.h>
#endif

///thread spical store
template <typename T>
class hy_tss_ptr
	//: private zr_noncopyable
{
public:
	// Constructor.
	hy_tss_ptr()
#ifdef _WIN32
		:tss_key_(TLS_OUT_OF_INDEXES)
#else
		:state_(0)
#endif
	{
	}

	// Destructor.
	~hy_tss_ptr()
	{
		unit();
	}

	hy_err_t init()
	{
#ifdef _WIN32
		tss_key_ = ::TlsAlloc();
		if (tss_key_ == TLS_OUT_OF_INDEXES)
		{
			return error();
		}		
#else
		if (::pthread_key_create(&tss_key_, 0) == 0)
		{
			state_ = 1;
		}
		else
		{
			return error();
		}
#endif
		return hy_right;
	}

	void unit()
	{
#ifdef _WIN32
		::TlsFree(tss_key_);
#else
		::pthread_key_delete(tss_key_);
		state_ = 0;
#endif	
	}

	// Get the value.
	operator T*() const
	{
#ifdef _WIN32
		return static_cast<T*>(::TlsGetValue(tss_key_));
#else
		return static_cast<T*>(::pthread_getspecific(tss_key_));
#endif

	}

	// Set the value.
	void operator=(T* value)
	{
#ifdef _WIN32
		::TlsSetValue(tss_key_, value);
#else
		::pthread_setspecific(tss_key_, value);
#endif	
	}

private:
#ifdef _WIN32
	DWORD tss_key_;
#else
	int state_;
	pthread_key_t tss_key_;
#endif	
};


#endif //_ZR_TSS_H_
